Add cosa import#4164
Conversation
|
Skipping CI for Draft Pull Request. |
|
@jlebon I have pushed a very dirty draft here (using a new PR as I'm getting permission error when I try to push to your branch). I'm getting error on I have set the |
What error are you seeing?
Yeah indeed, we should make it optional. |
This is the error if the import build is the only one available locally. |
ac369ad to
4f68cef
Compare
I found problem and fixed it now . |
For the record, the problem here was that This is normally handled by It'd probably make sense to factor out those idempotent bits from |
I'll take a look at that function, I skimmed through it to once. But with these changes I got a qemu image build, no errors. |
cd0f927 to
b9d955d
Compare
|
@jlebon, I have removed the |
There was a problem hiding this comment.
Thanks for working on this! Did a first pass here but would like to test drive it as well. Did you sanity-checking that the kola tests pass with a QEMU image built from an imported build? There is cosa diff also that would be useful here, though that doesn't also cover e.g. the QEMU image. Though in practice, the input to the QEMU build is the container image, so a cosa diff at the ostree level should cover these. Still, worth also doing a cosa buildextend-live, and cosa diff with the various --live options too to sanity-check they're identical, and then do a kola testiso run.
|
Make sure when testing this that you're testing with an FCOS built using https://github.com/coreos/fedora-coreos-config/blob/testing-devel/Containerfile and not what we currently push to https://quay.io/repository/fedora/fedora-coreos?tab=tags. |
I was testing it with images from quay.io. I will check this. |
|
Testing the gemini review integration /gemini review |
|
You can now remove the commit updating the lockfiles (see #4171) |
|
@jlebon I got qemu with the recent changes. Some of your PR comments are yet to be addressed. I'll be working on it soon. |
|
osbuild patch is merged. osbuild/osbuild#2148 |
|
Comments addressed! Also re-added the osbuild patch since it's merged upstream. |
d0be01d to
0ab5a02
Compare
dustymabe
left a comment
There was a problem hiding this comment.
Thanks for working on this! Added some comments.
This command takes as argument a `containers-transport(5)`-style pullspec and creates a new cosa build dir from it. It essentially bridges the gap between coreos/fedora-coreos-config#3348 and the rest of the cosa pipeline. Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
There's a massive gotcha with bash, which is that even with `set -e`, if you're capturing output from a function, e.g. `x=$(myfunc)`, `set -e` will not be turned on in that function. That made an error in that function much harder to diagnose because the command _kept going_ even though the function failed (and then the overall operation failed later on on a much less clear error). There's a bash option to enable this (`shopt inherit_errexit`), but I think actually that in general we shouldn't be capturing output from non-trivial bash functions. It's hard in bash to ensure clean stdout output and the longer a function gets, the harder it is to keep this up (notice e.g. how that function needs to be careful to `echo` everything to stderr). In this case, it's easy to rework the flow here to avoid this, so let's do that instead.
We now keep blob refs in the tmp repo to make importing OCI images more efficient by avoiding having to re-import identical layers. But then we also need to prune them. Do this. The semantic here is simple: we prune any blob ref not tied to one of the kept builds.
Treefile.json from rpm-ostree doesn't contain `name` in the `metadata` field from images built using podman build.
|
OK, addressed review comments! I ended up reworking this quite a bit in the process of wanting to clean up the data/metadata flow through the various functions. It looks very different, but it's really just shifting all the same pieces around to make it easier to follow. Also fixed a minor bug in the process (we were missing a |
Thanks. |
jbtrystram
left a comment
There was a problem hiding this comment.
Superficial LGTM as it touches some part i don't have experience with.
Thanks, that's nice !
Are we planning to have a cosa wrapper to do the container build using versionary to have a nicer build id like 20250717.dev.0 then import it ?
|
So one bug here is that Opened bootc-dev/bootc#1421 to fix this. |
dustymabe
left a comment
There was a problem hiding this comment.
LGTM
I made some comments here but we can either disregard them or merge them in a later PR if you don't want to wait for a CI cycle on this.
| if is_oci_imported: | ||
| import_oci_archive(tmpdir, tarfile, buildmeta['buildid']) |
There was a problem hiding this comment.
I think this part is still tripping me up a bit and I think it's the naming of things.
For example, we're calling checking is_oci_imported here and then calling import_oci_archive, but isn't the elif/else below also importing a .ociarchive file?
Maybe if we named the function import_container_built_ociarchive it would make more sense, because basically the different here that I see is in this case we are importing an archive that was created via podman build and in the other cases we are importing an archive that was generated by rpm-ostree.
I don't actually know if that rename suggestion is something we should do, just putting my thought process out there. Maybe just a comment would suffice.
There was a problem hiding this comment.
Yeah, it should probably be called was_oci_imported.
| if os.environ.get('COSA_PRIVILEGED', '') == '1': | ||
| if is_oci_imported: | ||
| import_oci_archive(tmpdir, tarfile, buildmeta['buildid']) | ||
| elif os.environ.get('COSA_PRIVILEGED', '') == '1': |
There was a problem hiding this comment.
not new to this PR but I don't really know why we need both an elif/else here for the legacy path based on COSA_PRIVILEGED. Would just using the unprivileged path work in both cases (just be slower)?
There was a problem hiding this comment.
Yes it would. The privileged path takes advantage of the fact that we already have a bare-user repo laying around that probably has a majority of the objects already.
| extract_image_json(workdir, commit) | ||
|
|
||
|
|
||
| def import_oci_archive(parent_tmpd, ociarchive, ref): |
There was a problem hiding this comment.
Comparing this to the legacy unpriv path above it seems like the biggest differences here are:
- handling of the blob refs
- we call
ostree container image pullversusostree container importis that right?
There was a problem hiding this comment.
Correct, yes. The framing is quite different. With ostree container import, the source of truth is an OSTree commit that was exported to a tarball and we're reconverting it into the exact original OSTree commit. With ostree container image pull, the source of truth is the container image, and we're importing that into the tmp repo to mesh with existing tooling.
| encoding='utf-8').splitlines() | ||
| subprocess.check_call(['ostree', 'pull-local', '--repo', 'tmp/repo', tmpd] + blob_refs) | ||
|
|
||
| return subprocess.check_output(['ostree', 'rev-parse', '--repo', 'tmp/repo', ref], encoding='utf-8').strip() |
There was a problem hiding this comment.
Might make things a little more obvious
| return subprocess.check_output(['ostree', 'rev-parse', '--repo', 'tmp/repo', ref], encoding='utf-8').strip() | |
| ostree_commit = subprocess.check_output(['ostree', 'rev-parse', '--repo', 'tmp/repo', ref], encoding='utf-8').strip() | |
| return ostree_commit |
| @@ -354,6 +360,42 @@ def import_ostree_commit(workdir, buildpath, buildmeta, extract_json=True, parti | |||
| extract_image_json(workdir, commit) | |||
|
|
|||
|
|
|||
There was a problem hiding this comment.
A comment here mentioning some callers expect the extracting ostree commit hash string to be returned might be useful.
jlebon
left a comment
There was a problem hiding this comment.
Thanks for the reviews! Let's get this in and do tweaks in follow-ups.
| if is_oci_imported: | ||
| import_oci_archive(tmpdir, tarfile, buildmeta['buildid']) |
There was a problem hiding this comment.
Yeah, it should probably be called was_oci_imported.
| if os.environ.get('COSA_PRIVILEGED', '') == '1': | ||
| if is_oci_imported: | ||
| import_oci_archive(tmpdir, tarfile, buildmeta['buildid']) | ||
| elif os.environ.get('COSA_PRIVILEGED', '') == '1': |
There was a problem hiding this comment.
Yes it would. The privileged path takes advantage of the fact that we already have a bare-user repo laying around that probably has a majority of the objects already.
| extract_image_json(workdir, commit) | ||
|
|
||
|
|
||
| def import_oci_archive(parent_tmpd, ociarchive, ref): |
There was a problem hiding this comment.
Correct, yes. The framing is quite different. With ostree container import, the source of truth is an OSTree commit that was exported to a tarball and we're reconverting it into the exact original OSTree commit. With ostree container image pull, the source of truth is the container image, and we're importing that into the tmp repo to mesh with existing tooling.
Address some comments from coreos#4164.
|
Follow-ups in #4227. |
Address some comments from coreos#4164.
Address some comments from #4164.
This command takes as argument a
containers-transport(5)-style pullspec and creates a new cosa build dir from it. It essentially bridges the gap between coreos/fedora-coreos-config#3348 and the rest of the cosa pipeline.co-authored by: Bipin B Narayan bbnaraya@redhat.com